package session;

import entity.Category;
import entity.Item;
import java.util.List;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;

/**
 * Rappresenta il gestore delle transazioni degli entity Item.
 *
 * @author Rachid Ouchary, Fabio Strocco, Max Passaghe, Marco Tansini.
 */
@Stateless
public class ItemFacade implements ItemFacadeRemote {
    @PersistenceContext(unitName = "WishLister-ejbPU")
    private EntityManager em;

    /**
     * Rende persistente un nuovo Item.
     *
     * @param item l'item da rendere persistente.
     */
    public void create(Item item) {
        em.persist(item);
    }

    /**
     * Aggiorna lo stato dell'item nel DB allo stato dell'item passato
     * come parametro.
     *
     * @param item l'item da aggiornare.
     */
    public void edit(Item item) {
        em.merge(item);
    }

    /**
     * Rimuove un item dal DB.
     *
     * @param item l'item da rimuovere.
     */
    public void remove(Item item) {
        em.remove(em.merge(item));
    }

    /**
     * Carica l'item con l'id specificato.
     *
     * @param id l'id dell'item da caricare.
     * @return l'item con l'id specificato, <code>null</code> se non esiste nel
     * DB.
     */
    public Item find(Long id) {
        return em.find(Item.class, id);
    }

    /**
     * Cerca l'oggetto nel database con i valori degli attributi specificati
     * come parametri.
     * @param categoria la categoria dell'oggetto.
     * @param descrizione la descrizione dell'oggetto.
     * @return l'oggetto se un oggetto con categoria e descrizione specificate
     * esiste, <code>null</code> altrimenti.
     */
    public Item findBy(Category categoria, String descrizione) {

        Query query = em.createNamedQuery(Item.FIND_ITEM);

        query.setParameter("categoria", categoria);
        query.setParameter("descrizione", descrizione);

        try {
            return (Item) query.getSingleResult();
        } catch (NoResultException ex) {
            return null;
        }
    }

    /**
     *
     * @return
     */
    public List<Item> findAll() {
        CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
        cq.select(cq.from(Item.class));
        return em.createQuery(cq).getResultList();
    }

    /**
     *
     * @param range
     * @return
     */
    public List<Item> findRange(int[] range) {
        CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
        cq.select(cq.from(Item.class));
        Query q = em.createQuery(cq);
        q.setMaxResults(range[1] - range[0]);
        q.setFirstResult(range[0]);
        return q.getResultList();
    }

    /**
     *
     * @return
     */
    public int count() {
        CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
        Root<Item> rt = cq.from(Item.class);
        cq.select(em.getCriteriaBuilder().count(rt));
        Query q = em.createQuery(cq);
        return ((Long) q.getSingleResult()).intValue();
    }
}
